namespace System.Xml.Serialization.Internal
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Globalization;

    [Serializable]
    internal class XmlFormatAttributes<T> : IXmlFormatAttributesInternal
    {
        [NonSerialized]
        private readonly Dictionary<string, XmlFormatterValue> _attributes;
        [NonSerialized]
        private readonly XmlAttributeOverrides _overrides;
        [NonSerialized]
        private XmlSerializer _serializer;
        [NonSerialized]
        private readonly Type _type;

        public XmlFormatAttributes()
        {
            this._type = typeof(T);
            this._attributes = new Dictionary<string, XmlFormatterValue>();
            this._overrides = new XmlAttributeOverrides();
        }

        public void Add(Type type, XmlAttributes attributes)
        {
            if (type != null && attributes != null)
            {
                string key = string.Format(CultureInfo.InvariantCulture, "{0}", type.Name);
                if (key != null)
                {
                    if (!this._attributes.ContainsKey(key))
                    {
                        this._attributes.Add(key, new XmlFormatterValue(attributes, type, key));
                    }
                }
            }
        }

        public void Add(Type type, string member, XmlAttributes attributes)
        {
            if (type != null && member != null && attributes != null)
            {
                string key = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", type.Name, member);
                if (key != null)
                {
                    if (!this._attributes.ContainsKey(key))
                    {
                        this._attributes.Add(key, new XmlFormatterValue(attributes, type, member));
                    }
                }
            }
        }

        public XmlFormatterValue GetAttributes()
        {
            string key = string.Format(CultureInfo.InvariantCulture, "{0}", this._type.Name);
            if (key != null)
            {
                if (!this._attributes.ContainsKey(key))
                {
                    XmlAttributes attributes = new XmlAttributes();
                    XmlFormatterValue format = new XmlFormatterValue(attributes, this._type, key);
                    this._attributes[key] = format;
                    return format;
                }
            }
            return (XmlFormatterValue)this._attributes[key];
        }

        public XmlFormatterValue GetAttributes(string member)
        {
            string key = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", this._type.Name, member);
            if (key != null)
            {
                if (!this._attributes.ContainsKey(key))
                {
                    XmlAttributes attributes = new XmlAttributes();
                    XmlFormatterValue format = new XmlFormatterValue(attributes, this._type, member);
                    this._attributes[key] = format;
                    return format;
                }
            }
            return (XmlFormatterValue)this._attributes[key];
        }

        public XmlAttributeOverrides Format
        {
            get
            {
                return this._overrides;
            }
        }

        public XmlSerializer RuntimeSerializer
        {
            get
            {
                return this._serializer;
            }
        }

        public void CreateRuntimeSerializer()
        {
            ICollection _keys = this._attributes.Keys;
            if (_keys != null)
            {
                IEnumerator enumerator = _keys.GetEnumerator();
                if (enumerator != null)
                {
                    while (enumerator.MoveNext())
                    {
                        string member = enumerator.Current as string;
                        if (member != null)
                        {
                            //PluginLog.WriteOutSync(string.Format(CultureInfo.InvariantCulture, "{0} : {1}", PluginTypeHelper.GetTypeName(_type), member));
                            XmlFormatterValue value = (XmlFormatterValue)this._attributes[member];
                            if (string.Equals(member, string.Format(CultureInfo.InvariantCulture, "{0}.{1}", value.Type.Name, value.Member)) && (this._overrides[value.Type, value.Member] == null))
                            {
                                this._overrides.Add(value.Type, value.Member, value.Attributes);
                            }
                            if (string.Equals(member, string.Format(CultureInfo.InvariantCulture, "{0}", value.Member)) && (this._overrides[value.Type] == null))
                            {
                                this._overrides.Add(value.Type, value.Attributes);
                            }
                        }
                    }
                }
            }
            this._serializer = new XmlSerializer(this._type, this._overrides);
        }
    }
}

